package orm

import (
	"my_framework/orm/internal/errs"
	"my_framework/orm/model"
	"strings"
)

type builder struct {
	sb    *strings.Builder
	model *model.Model
	args  []any

	dialect Dialect
	quoter  byte
}

func (b *builder) quote(name string) {
	b.sb.WriteByte(b.quoter)
	b.sb.WriteString(name)
	b.sb.WriteByte(b.quoter)
}

//func (b *builder) buildExpression(raw Expression) error {
//	switch exp := raw.(type) {
//	case nil:
//	case Predicate:
//		// 处理p
//		_, ok := exp.left.(Predicate)
//		if ok {
//			b.sb.WriteByte('(')
//		}
//		if err := b.buildExpression(exp.left); err != nil {
//			return err
//		}
//		if ok {
//			b.sb.WriteByte(')')
//		}
//
//		b.sb.WriteByte(' ')
//		b.sb.WriteString(exp.op.String())
//		b.sb.WriteByte(' ')
//
//		_, ok = exp.right.(Predicate)
//		if ok {
//			b.sb.WriteByte('(')
//		}
//		if err := b.buildExpression(exp.right); err != nil {
//			return err
//		}
//		if ok {
//			b.sb.WriteByte(')')
//		}
//	case Column:
//		b.sb.WriteByte('`')
//		b.sb.WriteString(exp.name)
//		b.sb.WriteByte('`')
//	//
//	case value:
//		b.sb.WriteByte('?')
//		b.addArg(exp.val)
//		//
//	default:
//		return errs.NewErrUnsupportedExpression(raw)
//	}
//	return nil
//}

func (s *builder) buildExpression(expr Expression) error {
	switch exp := expr.(type) {
	case nil:
	case Predicate:
		// 处理p
		_, ok := exp.left.(Predicate)
		if ok {
			s.sb.WriteByte('(')
		}
		if err := s.buildExpression(exp.left); err != nil {
			return err
		}
		if ok {
			s.sb.WriteByte(')')
		}

		if exp.op != "" {
			s.sb.WriteByte(' ')
			s.sb.WriteString(exp.op.String())
			s.sb.WriteByte(' ')
		}

		_, ok = exp.right.(Predicate)
		if ok {
			s.sb.WriteByte('(')
		}
		if err := s.buildExpression(exp.right); err != nil {
			return err
		}
		if ok {
			s.sb.WriteByte(')')
		}
	case Column:
		// 防止where加as
		exp.alias = ""
		return s.buildColumn(exp)
	case value:
		s.sb.WriteByte('?')
		s.addArg(exp.val)
	case RawExpr:
		s.sb.WriteByte('(')
		s.sb.WriteString(exp.raw)
		s.addArg(exp.args...)
		s.sb.WriteByte(')')
	default:
		return errs.NewErrUnsupportedExpression(expr)
	}
	return nil
}

func (s *builder) buildColumn(c Column) error {
	fd, ok := s.model.FieldMap[c.name]
	// 传入了错误的字段
	if !ok {
		return errs.NewErrUnknownField(c.name)
	}
	//s.sb.WriteByte('`')
	//s.sb.WriteString(fd.ColName)
	//s.sb.WriteByte('`')
	s.quote(fd.ColName)
	if c.alias != "" {
		s.sb.WriteString(" AS ")
		s.quote(c.alias)
		//s.sb.WriteString(" AS `")
		//s.sb.WriteString(c.alias)
		//s.sb.WriteByte('`')
	}
	return nil
}

func (s *builder) addArg(vals ...any) *builder {
	if len(vals) == 0 {
		return nil
	}
	if s.args == nil {
		s.args = make([]any, 0, 8)
	}
	s.args = append(s.args, vals...)
	return s
}

func (b *builder) buildPredicates(ps []Predicate) error {
	p := ps[0]
	for i := 1; i < len(ps); i++ {
		p = p.And(ps[i])
	}
	return b.buildExpression(p)
}
